﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Model;
using Model.Enum;
using Components;
using System.Text.RegularExpressions;

namespace Controls
{
    public partial class SearchItem : UserControl
    {
        #region 属性
        #endregion

        private string _searchString;
        private List<TextValuePair> fields = null;
        private Dictionary<string, PsDataType> _tmpCol = null;
        private Dictionary<string, int> _tmpIndex = null;

        public SearchItem()
        {
            InitializeComponent();
        }

        public SearchItem(params TextValuePair[] list)
            : this()
        {
            InitializeComponent();

            this.fields.AddRange(list);
        }

        public void CreateSearchPanel()
        {
            this.field.DataSource = fields;
            this.field.DisplayMember = "Text";
            this.field.ValueMember = "Value";
        }

        private void stspAddCondition_Click(object sender, EventArgs e)
        {
            if (!@CheckGrid(false)) return;

            DataGridViewRow dr = new DataGridViewRow();
            dr.CreateCells(this.dgvCondition,
                new object[] { this.relation.Items[0] });

            dgvCondition.Rows.Add(dr);

            DataGridViewRow newDr = dgvCondition.Rows[dgvCondition.Rows.Count - 1];

            if (this.dgvCondition.Rows.Count == 1)
            {
                this.dgvCondition.Rows[0].Cells["relation"].ReadOnly = true; //第一行的关系符不显示
            }

            newDr.Cells[0].Selected = true; //选择新行
        }

        public void AddColumn(TextValuePair tvp)
        {
            if (null == fields)
            {
                fields = new List<TextValuePair>();
                _tmpCol = new Dictionary<string, PsDataType>();
                _tmpIndex = new Dictionary<string, int>();
            }

            _tmpCol.Add(tvp.Value, tvp.DataType);
            _tmpIndex.Add(tvp.Value, _tmpCol.Count - 1); //存储位置关系
            fields.Add(tvp);
        }

        private bool EmptyCollection(System.Collections.IList lst)
        {
            return lst == null || lst.Count == 0;
        }

        //字段下拉框选项改变了的时候，改变操作符下拉框的选项
        void cbxField_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (null == this.dgvCondition.CurrentCell) return;
            string colName = this.dgvCondition.Columns[this.dgvCondition.CurrentCell.ColumnIndex].Name;

            if ("field" != colName)
            {
                return;
            }

            DataGridViewComboBoxEditingControl cbxField = sender as DataGridViewComboBoxEditingControl;
            Model.TextValuePair tv = cbxField.SelectedItem as Model.TextValuePair;//当选择的字段名称改变时，重置操作符
            if (tv == null) return;

            DataGridViewComboBoxCell cell = this.dgvCondition.CurrentRow.Cells["op"] as DataGridViewComboBoxCell;
            GetOperateList(tv.DataType, cell); //绑定下拉框
        }

        #region 操作符

        //根据字段的类型选择合适的操作符
        protected void GetOperateList(PsDataType dp, DataGridViewComboBoxCell cb)
        {
            List<TextValuePair> lst = new List<TextValuePair>();

            if (null == cb) return;
            //cb.DataSource = null;

            if (dp == PsDataType.Date || dp == PsDataType.Datetime) //日期
            {
                lst.Add(new TextValuePair("等于", " datediff(d,{1},Convert(datetime,'{0}')) = 0 "));
                lst.Add(new TextValuePair("早于", " {1} > CONVERT(datetime,'{0}')"));
                lst.Add(new TextValuePair("晚于", " {1} < CONVERT(datetime,'{0}')"));
            }
            else if (dp == PsDataType.Num || dp == PsDataType.NumThanZero || dp == PsDataType.NumThanZeroOrEqualZero
                || dp == PsDataType.Int || dp == PsDataType.IntThanZero || dp == PsDataType.IntThanZeroOrEqualZero) //数字
            {
                lst.Add(new TextValuePair("等于", " {1} = CONVERT(numeric(12,6), '{0}')"));
                lst.Add(new TextValuePair("大于", " {1} > CONVERT(numeric(12,6), '{0}')"));
                lst.Add(new TextValuePair("大于或等于", " {1} >= CONVERT(numeric(12,6), '{0}')"));
                lst.Add(new TextValuePair("小于", " {1} < CONVERT(numeric(12,6), '{0}')"));
                lst.Add(new TextValuePair("小于或等于", " {1} <= CONVERT(numeric(12,6), '{0}')"));
                lst.Add(new TextValuePair("不等于", " {1} <> CONVERT(numeric(12,6), '{0}')"));
            }
            else //字符串等其他
            {
                lst.Add(new TextValuePair("等于", " {1} = '{0}' "));
                lst.Add(new TextValuePair("包含", " {1} LIKE '%{0}%' "));
                lst.Add(new TextValuePair("不包含", " {1} NOT LIKE '%{0}%'  "));
                lst.Add(new TextValuePair("以……开头", " {1} LIKE '{0}%' "));
                lst.Add(new TextValuePair("以……结尾", " {1} LIKE '%{0}' "));
            }

            cb.DataSource = lst;
            cb.DisplayMember = "Text";
            cb.ValueMember = "Value";
            cb.Tag = dp;
        }

        //检查操作符
        protected bool CheckOperate(PsDataType dp, string text)
        {
            if (string.IsNullOrEmpty(text)) return true;

            if (dp == PsDataType.Date || dp == PsDataType.Datetime)
            {
                if (!Validation.IsDate(text))
                {
                    MessageBox.Show("您输入的查询条件应该为日期格式。标准的格式是四位年-两位月-两位日。\n例如：2010-10-10 。", "提示");
                    return false;
                }
            }
            else if (dp == PsDataType.Num || dp == PsDataType.NumThanZero || dp == PsDataType.NumThanZeroOrEqualZero
                || dp == PsDataType.Int || dp == PsDataType.IntThanZero || dp == PsDataType.IntThanZeroOrEqualZero) //数字
            {
                if (!Validation.IsFloat(text))
                {
                    MessageBox.Show("您输入的查询条件应该为数字格式。\n\n输入的内容中不应该有字符、汉字或特殊符号。", "提示");
                    return false;
                }
            }

            return true;
        }

        #endregion

        /// <summary>
        /// 检查当前录入的查询条件是否正确
        /// </summary>
        /// <param name="_valBracket">是否验证括号</param>
        /// <returns></returns>
        public bool CheckGrid(bool _valBracket)
        {
            string colVal;
            string content;
            string op;
            string relation;
            string lbracket;
            string rbracket;
            DataGridViewComboBoxCell cb = null;

            this.dgvCondition.EndEdit(); //结束当前的编辑状态
            int lbracketCount = 0; //共有多少个左边括号
            int rbracketCount = 0; //共有多少个左边括号
            StringBuilder sb = new StringBuilder(" ( ");
            foreach (DataGridViewRow dr in this.dgvCondition.Rows)
            {
                colVal = Validation.ToString(dr.Cells["field"].Value);
                if (string.IsNullOrEmpty(colVal))
                {
                    MessageBox.Show("第（" + (dr.Index + 1) + "）行[查询列名]必须选择！", "提示");
                    dr.Cells["field"].Selected = true;
                    return false;
                }

                op = Validation.ToString(dr.Cells["op"].Value);
                if (string.IsNullOrEmpty(op))
                {
                    MessageBox.Show("第（" + (dr.Index + 1) + "）行[操作符]必须选择！", "提示");
                    dr.Cells["op"].Selected = true;
                    return false;
                }

                content = Validation.ToString(dr.Cells["content"].Value); //查询内容

                if (!CheckOperate(_tmpCol[colVal], content)) //检验查询内容是否正确
                {
                    dr.Cells["content"].Selected = true;
                    return false;
                }

                lbracket = Validation.ToString(dr.Cells["lbracket"].Value);
                rbracket = Validation.ToString(dr.Cells["rbracket"].Value);

                lbracketCount += lbracket.Length; //累加左边括号
                rbracketCount += rbracket.Length; //累加右边括号

                relation = Validation.ToString(dr.Cells["relation"].Value);
                cb = dr.Cells["op"] as DataGridViewComboBoxCell;
                op = Validation.ToString(cb.Value);

                //第一行不需要加入关系运算符
                sb.AppendFormat(" {0} {1} {2} {3} ", dr.Index == 0 ? "" : relation.Replace("且", "AND").Replace("或", "OR"),
                    lbracket, getSearchWhere(fields[_tmpIndex[colVal]], content, op), rbracket);
            }

            if (sb.Length < 4) //仅有大括号
            {
                sb.Append(" 1 = 1 ");
            }

            sb.Append(")");

            if (_valBracket)
            {
                if (lbracketCount != rbracketCount)
                {
                    MessageBox.Show("\"(\"与\")\"的数量不对应，请检查！", " 提示");
                    return false;
                }
            }

            this._searchString = sb.ToString();

            return true;
        }

        /// <summary>
        /// 返回搜索字符串
        /// </summary>
        public string SearchString
        {
            get { return _searchString; }
        }

        private void dgvCondition_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            string editColumnName = this.dgvCondition.Columns[this.dgvCondition.CurrentCell.ColumnIndex].Name; //当前编辑行的列名

            DataGridViewComboBoxEditingControl c = e.Control as DataGridViewComboBoxEditingControl;
            if (c == null) return;
            c.SelectedIndexChanged -= new EventHandler(cbxField_SelectedIndexChanged);

            if ("field" == editColumnName)
            {
                c.SelectedIndexChanged += new EventHandler(cbxField_SelectedIndexChanged);
            }
        }

        private void dgvCondition_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            //MessageBox.Show(e.Exception.Message);
        }

        private void stspLBracket_Click(object sender, EventArgs e)
        {
            int rowIndex = this.dgvCondition.CurrentRow.Index;
            if (rowIndex < 0) return;

            this.dgvCondition["lbracket", rowIndex].Value += "(";
        }

        private void stspRBracket_Click(object sender, EventArgs e)
        {
            int rowIndex = this.dgvCondition.CurrentRow.Index;
            if (rowIndex < 0) return;

            this.dgvCondition["rbracket", rowIndex].Value += ")";
        }

        private void stspDLBracket_Click(object sender, EventArgs e)
        {
            int rowIndex = this.dgvCondition.CurrentRow.Index;
            if (rowIndex < 0) return;

            object nowVal = this.dgvCondition["lbracket", rowIndex].Value;
            if (null == nowVal || 0 == nowVal.ToString().Length) return;

            Regex reg = new Regex(@"^\(");
            this.dgvCondition["lbracket", rowIndex].Value = reg.Replace(nowVal.ToString(), "");
        }

        private void stspDRBracket_Click(object sender, EventArgs e)
        {
            int rowIndex = this.dgvCondition.CurrentRow.Index;
            if (rowIndex < 0) return;

            object nowVal = this.dgvCondition["rbracket", rowIndex].Value;
            if (null == nowVal || 0 == nowVal.ToString().Length) return;

            Regex reg = new Regex(@"^\)");
            this.dgvCondition["rbracket", rowIndex].Value = reg.Replace(nowVal.ToString(), "");
        }

        private string getSearchWhere(TextValuePair tv, string value, string op)
        {
            if (string.IsNullOrEmpty(value)) return " 1 = 1 ";

            if (tv == null || op == null) return "1 = 1 ";

            string s = " 1 = 1 ";
            PsDataType tag = _tmpCol[tv.Value];

            if (!string.IsNullOrEmpty(value))
            {
                //日期 => 不合法的字符，替换成false条件
                if ((tag == PsDataType.Date || tag == PsDataType.Datetime || tag == PsDataType.Time)
                       && !Validation.IsDate(value))
                {
                    s = " 1 = 0 ";
                }
                else if ((tag == PsDataType.Int || tag == PsDataType.IntThanZero || tag == PsDataType.IntThanZeroOrEqualZero
                    || tag == PsDataType.Num || tag == PsDataType.NumThanZero || tag == PsDataType.NumThanZeroOrEqualZero)
                    && !Validation.IsFloat(value, 10)) //数字 暂时只支持10位的查询
                {
                    s = " 1 = 0 ";
                }
                else
                {
                    s = string.Format(op, value, tv.OtherName);
                }
            }

            string condition = (string.IsNullOrEmpty(value)) ? (string.Format("( {0} OR {1} IS NULL)", s, tv.OtherName))
                                                                : s.ToString();
            return condition;
        }

        private void stspDel_Click(object sender, EventArgs e)
        {
            if (null == this.dgvCondition.SelectedCells || 0 == this.dgvCondition.SelectedCells.Count)
                return;

            int rowindex = this.dgvCondition.SelectedCells[0].RowIndex;
            if (rowindex < 0) return;

            if (MessageBox.Show("确定删除？", "提示", MessageBoxButtons.OKCancel) != DialogResult.OK)
                return;

            this.dgvCondition.Rows.RemoveAt(rowindex);

            //删除后如果仍然有行存在，那么将第一行设置的关系运算符设置成只读
            if (this.dgvCondition.Rows.Count > 0)
            {
                DataGridViewComboBoxCell cb = this.dgvCondition.Rows[0].Cells[0] as DataGridViewComboBoxCell;
                cb.ReadOnly = true;
                cb.Value = " 且 ";
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            this.dgvCondition.Font = this.Font;
        }
    }
}
